﻿#region << 版 本 注 释 >>
/*----------------------------------------------------------------
 * 版权所有 (c) 2022 北京超维景生物科技有限公司 保留所有权利。
 * 
 * 创建者：huangyang
 * 电子邮箱：huangyang@tvscope.cn
 * 创建时间：2023/3/3 9:40:55
 * 版本：V1.0.0
 * 描述：
 *
 * ----------------------------------------------------------------
 * 修改人：
 * 时间：
 * 修改说明：
 *
 * 版本：V1.0.1
 *----------------------------------------------------------------*/
#endregion << 版 本 注 释 >>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ImageK.Java;

namespace ImageK.Text
{
    public class TextCanvas:UserControl
    {
        TextPanel tp;
        Font fFont;
        FontMetrics fMetrics;
        Graphics gImage;
        private Brush _gBrush;
        private Pen _gPen;
        Bitmap iImage;
        bool antialiased;

        public TextCanvas()
        {
            this.Dock = DockStyle.Fill;
        }

        public TextCanvas(TextPanel tp):this()
        {
            this.tp = tp;
            // addMouseListener(tp);
            // addMouseMotionListener(tp);
            // addKeyListener(tp);
            // addMouseWheelListener(tp);
        }

        public void setBounds(int x, int y, int width, int height)
        {
            this.Bounds = new Rectangle(x, y, width, height);
			// tp.adjustVScroll();
			// tp.adjustHScroll();
			iImage = null;
		}

		public void update(Graphics g)
		{
			paint(g);
		}

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            paint(e.Graphics);
		}

		public void paint(Graphics g)
		{
            if (tp == null || g == null) return;
            Size d = this.Size;
            int iWidth = d.Width;
            int iHeight = d.Height;

            if (iWidth <= 0 || iHeight <= 0) return;
            // g.setColor(Color.LightGray);

            if (iImage == null)
                makeImage(iWidth, iHeight);
            if (tp.iRowHeight == 0 || (tp.iColWidth.Length > 0 && tp.iColWidth[0] == 0 && tp.iRowCount > 0))
            {
				//todo:
				// tp.iRowHeight = fMetrics.getHeight() + 2;
                tp.iRowHeight = 20;

				for (int i = 0; i < tp.iColCount; i++)
                    calcAutoWidth(i);
				//todo:
                // tp.adjustHScroll();
                // tp.adjustVScroll();
            }
            _gBrush = new SolidBrush(Color.White);
            gImage.FillRectangle(_gBrush,0, 0, iWidth, iHeight);
            if (tp.headings)
                drawColumnLabels(iWidth);
            int y = tp.iRowHeight + 1;
            // int y = tp.iRowHeight + 1 - tp.iY;
            int j = 0;
            while (y < tp.iRowHeight + 1)
            {
                j++;
                y += tp.iRowHeight;
            }
            tp.iFirstRow = j;
            y = tp.iRowHeight + 1;
            for (; y < iHeight && j < tp.iRowCount; j++, y += tp.iRowHeight)
            {
                int x = -tp.iX;
                for (int i = 0; i < tp.iColCount; i++)
                {
                    if (i >= tp.iColWidth.Length) break;
                    int w = tp.iColWidth[i];
                    Color b = Color.White, t = Color.Black;
                    if (j >= tp.selStart && j <= tp.selEnd)
                    {
                        int w2 = w;
                        if (tp.iColCount == 1)
                            w2 = iWidth;
                        b = Color.Black;
                        t = Color.White;
                        _gBrush = new SolidBrush(b);
                        gImage.FillRectangle(_gBrush, x, y, w2 - 1, tp.iRowHeight);
                    }
                    _gBrush = new SolidBrush(t);

					string str = getChars(i, j);
                    if (str != null)
                    {
						// gImage.drawChars(chars, 0, chars.length, x + 2, y + tp.iRowHeight - 5);
                        gImage.DrawString(str,new Font("Arial",10),_gBrush,new PointF(x + 2, y));
					}
                        
                    x += w;
                }
            }
            if (iImage != null)
                g.DrawImage(iImage, new PointF(0,0));
        }


		void makeImage(int iWidth, int iHeight)
		{
			iImage = new Bitmap(iWidth, iHeight);
			if (gImage != null)
				gImage.Dispose();
			gImage = Graphics.FromImage(iImage);
			// gImage.setFont(fFont);
			// Java2.setAntialiasedText(gImage, antialiased);
            if (fMetrics == null)
                fMetrics = new FontMetrics(gImage);
        }

		void drawColumnLabels(int iWidth)
		{
            _gPen = new Pen(Color.DarkGray);
			gImage.DrawLine(_gPen, 0, tp.iRowHeight, iWidth, tp.iRowHeight);
			int x = -tp.iX;
			for (int i = 0; i < tp.iColCount; i++)
			{
				int w = tp.iColWidth[i];
                _gBrush = new SolidBrush(Color.LightGray);
				gImage.FillRectangle(_gBrush, x + 1, 0, w, tp.iRowHeight);
                _gBrush = new SolidBrush(Color.Black);
				if (tp.sColHead[i] != null)
					gImage.DrawString(tp.sColHead[i], new Font("Arial", 10),_gBrush, x + 2, 0);
				if (tp.iColCount > 0)
                {
                    _gPen = new Pen(Color.DarkGray);
					gImage.DrawLine(_gPen, x + w - 1, 0, x + w - 1, tp.iRowHeight - 1);
                    _gPen = new Pen(Color.White);
					gImage.DrawLine(_gPen, x + w, 0, x + w, tp.iRowHeight - 1);
				}
				x += w;
			}

            _gBrush = new SolidBrush(Color.LightGray);
			gImage.FillRectangle(_gBrush, 0, 0, 1, tp.iRowHeight);
			gImage.FillRectangle(_gBrush, x + 1, 0, iWidth - x, tp.iRowHeight);
			//gImage.drawLine(0,0,0,iRowHeight-1);
            _gPen = new Pen(Color.DarkGray);
			gImage.DrawLine(_gPen, 0, 0, iWidth, 0);
		}

		string getChars(int column, int row)
		{
			if (tp == null || tp.vData == null)
				return null;
			if (row >= tp.vData.Count)
				return null;
			char[] chars = row < tp.vData.Count ? (char[])(tp.vData[row]) : null;
			if (chars == null || chars.Length == 0)
				return null;

			if (tp.iColCount == 1)
				return new string(chars);

			int start = 0;
			int tabs = 0;
			int length = chars.Length;

			while (column > tabs)
			{
				if (chars[start] == '\t')
					tabs++;
				start++;
				if (start >= length)
					return null;
			};
			if (start < 0 || start >= chars.Length)
			{
				// System.out.println("start=" + start + ", chars.length=" + chars.length);
				return null;
			}
			if (chars[start] == '\t')
				return null;

			int end = start;
			while (chars[end] != '\t' && end < (length - 1))
				end++;
			if (chars[end] == '\t')
				end--;

			char[] chars2 = new char[end - start + 1];
			for (int i = 0, j = start; i < chars2.Length; i++, j++)
			{
				chars2[i] = chars[j];
			}
			return new string(chars2) ;
		}

		public void calcAutoWidth(int column)
		{
			if (tp.sColHead == null || column >= tp.iColWidth.Length || gImage == null)
				return;
			if (fMetrics == null)
				fMetrics = new FontMetrics(gImage);
			int w = 15;
			int maxRows = 20;
			if (column == 0 && tp.sColHead[0].Equals(" "))
				w += 5;
			else
			{
				w = Math.Max(w, (int)fMetrics.StringWidth(tp.sColHead[column]));
			}
			int rowCount = Math.Min(tp.iRowCount, maxRows);
			for (int row = 0; row < rowCount; row++)
			{
				string str = getChars(column, row);
				if (str != null)
					w = Math.Max(w, (int)fMetrics.StringWidth(str));
			}
			//System.out.println("calcAutoWidth: "+column+"  "+tp.iRowCount);
			string chars = tp.iRowCount > 0 ? getChars(column, tp.iRowCount - 1) : null;
			if (chars != null)
				w = Math.Max(w, (int)fMetrics.StringWidth(chars));
			if (column < tp.iColWidth.Length)
				tp.iColWidth[column] = w + 15;
		}
	}
}
